/**
 * 这个版本增加链式调用
 * @param {*} executor 
 */

function MyPromise(executor) {
    // 1、执行的基本结构
    let self = this;

    self.status = 'pending'; // 状态
    self.value = null; //成功的结果
    self.reason = null; //失败的原因
    // 7、异步失败，则添加数组，将then方法中的回调缓存
    self.successCallBack = [];
    self.failCallBack = [];
    // 4、判断状态，做相应的处理
    // 成功回调
    function resolve(value) {
        if (self.status === 'pending') {
            // 保存成功结果
            self.value = value;
            self.status = 'fulfilled';
            // 9、依次取出执行
            self.successCallBack.forEach(fn => fn(value))
        }
    }
    // 失败回调
    function reject(resaon) {
        if (self.status === 'pending') {
            // 保存失败原因
            self.reason = resaon;
            self.status = 'rejected';
            // 9、依次取出执行
            self.failCallBack.forEach(fn => fn(resaon))
        }
    }

    // 3、执行一下函数
    try {
        executor(resolve, reject)
    } catch (e) {
        console.log('executor执行出错了');
        reject(e);
    }
}

// 2、then 方法
MyPromise.prototype.then = function (onFulfilled, onRejected) {
    // 5、状态改变调用then方法
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (data) { resolve(data) };
    onRejected = typeof onRejected === 'function' ? onRejected : function (err) { throw err };
    // 10、想要实现链式调用，那么就返回一个Promise即可
    return new MyPromise((resove, reject) => {
        if (this.status === 'fulfilled') {
            try {
                let X = onFulfilled(this.value);
                // 判断当前的返回值是 不是Promise 是的话，就执行then函数，不是就直接返回值
                X instanceof MyPromise ? X.then(resove, reject) : resove(X);
            } catch (e) {
                reject(e);
            }
        } else if (this.status === 'rejected') {
            try {
                let X = onRejected(this.reason);
                // 判断当前的返回值是 不是Promise 是的话，就执行then函数，不是就直接返回值
                X instanceof MyPromise ? X.then(resove, reject) : resove(X);
            } catch (e) {
                reject(e);
            }
        } else {
            // 8、pending状态，缓存起来
            // 对于pading状态的时候，判断返回值是不是Promise ，所以只能用函数包裹一下
            this.successCallBack.push(() => {
                try {
                    let X = onFulfilled(this.value);
                    X instanceof MyPromise ? X.then(resove, reject) : resove(X);
                } catch (e) {
                    reject(e);
                }
            });
            this.failCallBack.push(() => {
                try {
                    let X = onRejected(this.reason);
                    X instanceof MyPromise ? X.then(resove, reject) : resove(X);
                } catch (e) {
                    reject(e);
                }
            });
        }
    })
}

// 11、返回一个catch方法
MyPromise.prototype.catch = function (fn) {
    return this.then(null, fn);
}
// 测试
let prom = new MyPromise((resolve, reject) => {
    console.log('12343242');
    // resolve('OK;e ')
    // 6、尝试异步--异步失败
    setTimeout(() => {
        reject(234)
    }, 500)
}).then((res) => {
    console.log('res', res);
    return 345435;
}, rej => {
    console.log('rej', rej);
    return new MyPromise((res, rej) => {
        rej('OK')
    })
}).then(res => {
    console.log('二段RES', res);
}).catch(e => { console.log('err', e) })

// let test2 = new MyPromise((res,rej)=>{
//     res(234354);
// })

// test2.then(fufilled=> {
//     console.log('fill',fufilled);
//     return test2
// }).then(res=>{
//     console.log('res',res);
// });




// new Promise((resolve, reject) => {
//     console.log('12343242');
//     // resolve('OK;e ')
//     // 6、尝试异步--异步失败
//     setTimeout(() => {
//         reject(234)
//     }, 500)

// }).then((res) => {
//     console.log('res', res);
//     return 345435;
// },rej=>{
//     console.log('rej',rej);
//     return new Promise((res,rej)=>{
//         rej('OK')
//     })
// }).then(res=>{
//     console.log('二段RES',res);
// }).catch(e=>{console.log('err',e)})